/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/** @defgroup socket Socket
* @ingroup libc
*/



#ifndef _SYS_SOCKET_H_
#define _SYS_SOCKET_H_

#include <sys/cdefs.h>
#include <sys/types.h>
#ifndef __LITEOS__
#include <linux/socket.h>
#else
#include <liteos/socket.h>
#endif

#include <asm/fcntl.h>
#include <asm/socket.h>
#ifndef __LITEOS__
#include <linux/sockios.h>
#include <linux/uio.h>
#include <linux/types.h>
#include <linux/compiler.h>
#else
#include <liteos/sockios.h>
#include <liteos/uio.h>
#include <liteos/types.h>
#include <liteos/compiler.h>
#endif

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */


#define sockaddr_storage __kernel_sockaddr_storage
typedef unsigned short sa_family_t;

struct timespec;

/*  Only the following macro definitions are supported:
 *  SOCK_STREAM
 *  SOCK_DGRAM
 *  SOCK_RAW
 *  SOCK_NONBLOCK
 */
#ifdef __mips__
#define SOCK_DGRAM      1
#define SOCK_STREAM     2
#else
#define SOCK_STREAM     1
#define SOCK_DGRAM      2
#endif
#define SOCK_RAW        3
#define SOCK_RDM        4
#define SOCK_SEQPACKET  5
#define SOCK_DCCP       6
#define SOCK_PACKET     10

#define SOCK_CLOEXEC O_CLOEXEC
#define SOCK_NONBLOCK O_NONBLOCK

enum {
  SHUT_RD = 0,
#define SHUT_RD         0
  SHUT_WR,
#define SHUT_WR         1
  SHUT_RDWR
#define SHUT_RDWR       2
};

struct sockaddr {
  sa_family_t sa_family;
  char sa_data[14];
};

struct linger {
  int l_onoff;
  int l_linger;
};

struct msghdr {
  void* msg_name;
  socklen_t msg_namelen;
  struct iovec* msg_iov;
  size_t msg_iovlen;
  void* msg_control;
  size_t msg_controllen;
  int msg_flags;
};

struct mmsghdr {
  struct msghdr msg_hdr;
  unsigned int msg_len;
};

struct cmsghdr {
  size_t cmsg_len;
  int cmsg_level;
  int cmsg_type;
};

#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr((mhdr), (cmsg))
#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
#define CMSG_DATA(cmsg) (((unsigned char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
#define CMSG_FIRSTHDR(msg) \
  ((msg)->msg_controllen >= sizeof(struct cmsghdr) \
   ? (struct cmsghdr*) (msg)->msg_control : (struct cmsghdr*) NULL)
#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) &&   (cmsg)->cmsg_len <= (unsigned long)   ((mhdr)->msg_controllen -   ((char*)(cmsg) - (char*)(mhdr)->msg_control)))

struct cmsghdr* __cmsg_nxthdr(struct msghdr*, struct cmsghdr*);

#define SCM_RIGHTS 0x01
#define SCM_CREDENTIALS 0x02
#define SCM_SECURITY 0x03

struct ucred {
  pid_t pid;
  uid_t uid;
  gid_t gid;
};

/*  Only the following macro definitions are supported:
 *  AF_INET
 *  AF_PACKET
 */
#define AF_UNSPEC 0
#define AF_UNIX 1
#define AF_LOCAL 1
#define AF_INET 2
#define AF_AX25 3
#define AF_IPX 4
#define AF_APPLETALK 5
#define AF_NETROM 6
#define AF_BRIDGE 7
#define AF_ATMPVC 8
#define AF_X25 9
#define AF_INET6 10
#define AF_ROSE 11
#define AF_DECnet 12
#define AF_NETBEUI 13
#define AF_SECURITY 14
#define AF_KEY 15
#define AF_NETLINK 16
#define AF_ROUTE AF_NETLINK
#define AF_PACKET 17
#define AF_ASH 18
#define AF_ECONET 19
#define AF_ATMSVC 20
#define AF_RDS 21
#define AF_SNA 22
#define AF_IRDA 23
#define AF_PPPOX 24
#define AF_WANPIPE 25
#define AF_LLC 26
#define AF_CAN 29
#define AF_TIPC 30
#define AF_BLUETOOTH 31
#define AF_IUCV 32
#define AF_RXRPC 33
#define AF_ISDN 34
#define AF_PHONET 35
#define AF_IEEE802154 36
#define AF_CAIF 37
#define AF_ALG 38
#define AF_NFC 39
#define AF_VSOCK 40
#define AF_MAX 41

#define PF_UNSPEC AF_UNSPEC
#define PF_UNIX AF_UNIX
#define PF_LOCAL AF_LOCAL
#define PF_INET AF_INET
#define PF_AX25 AF_AX25
#define PF_IPX AF_IPX
#define PF_APPLETALK AF_APPLETALK
#define PF_NETROM AF_NETROM
#define PF_BRIDGE AF_BRIDGE
#define PF_ATMPVC AF_ATMPVC
#define PF_X25 AF_X25
#define PF_INET6 AF_INET6
#define PF_ROSE AF_ROSE
#define PF_DECnet AF_DECnet
#define PF_NETBEUI AF_NETBEUI
#define PF_SECURITY AF_SECURITY
#define PF_KEY AF_KEY
#define PF_NETLINK AF_NETLINK
#define PF_ROUTE AF_ROUTE
#define PF_PACKET AF_PACKET
#define PF_ASH AF_ASH
#define PF_ECONET AF_ECONET
#define PF_ATMSVC AF_ATMSVC
#define PF_RDS AF_RDS
#define PF_SNA AF_SNA
#define PF_IRDA AF_IRDA
#define PF_PPPOX AF_PPPOX
#define PF_WANPIPE AF_WANPIPE
#define PF_LLC AF_LLC
#define PF_CAN AF_CAN
#define PF_TIPC AF_TIPC
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_IUCV AF_IUCV
#define PF_RXRPC AF_RXRPC
#define PF_ISDN AF_ISDN
#define PF_PHONET AF_PHONET
#define PF_IEEE802154 AF_IEEE802154
#define PF_CAIF AF_CAIF
#define PF_ALG AF_ALG
#define PF_NFC AF_NFC
#define PF_VSOCK AF_VSOCK
#define PF_MAX AF_MAX

#define SOMAXCONN 128

/*  Only the following macro definitions are supported:
 *  MSG_PEEK
 *  MSG_DONTWAIT
 *  MSG_MORE
 */
#define MSG_OOB 1
#define MSG_PEEK 2
#define MSG_DONTROUTE 4
#define MSG_TRYHARD 4
#define MSG_CTRUNC 8
#define MSG_PROBE 0x10
#define MSG_TRUNC 0x20
#define MSG_DONTWAIT 0x40
#define MSG_EOR 0x80
#define MSG_WAITALL 0x100
#define MSG_FIN 0x200
#define MSG_SYN 0x400
#define MSG_CONFIRM 0x800
#define MSG_RST 0x1000
#define MSG_ERRQUEUE 0x2000
#define MSG_NOSIGNAL 0x4000
#define MSG_MORE 0x8000
#define MSG_WAITFORONE 0x10000
#define MSG_FASTOPEN 0x20000000
#define MSG_CMSG_CLOEXEC 0x40000000
#define MSG_EOF MSG_FIN
#define MSG_CMSG_COMPAT 0

#define SOL_IP 0
#define SOL_TCP 6
#define SOL_UDP 17
#define SOL_IPV6 41
#define SOL_ICMPV6 58
#define SOL_SCTP 132
#define SOL_RAW 255
#define SOL_IPX 256
#define SOL_AX25 257
#define SOL_ATALK 258
#define SOL_NETROM 259
#define SOL_ROSE 260
#define SOL_DECNET 261
#define SOL_X25 262
#define SOL_PACKET 263
#define SOL_ATM 264
#define SOL_AAL 265
#define SOL_IRDA 266
#define SOL_NETBEUI 267
#define SOL_LLC 268
#define SOL_DCCP 269
#define SOL_NETLINK 270
#define SOL_TIPC 271

#define IPX_TYPE 1

#ifdef __i386__
# define __socketcall extern __attribute__((__cdecl__))
#else
# define __socketcall extern
#endif

/**
* @ingroup  socket
*
* @par Description:
* This API extracts the first connection request on the queue of pending connections
* for the listening socket 's', creates a new connected socket, and returns a new
* file descriptor  referring to that  socket. The newly created socket is not in the
* the listening state. The original socket 's' is unaffected by this call.
*
* @param  s          [IN]     Specifies a socket that was created with socket(), has been bound to an address with bind(), and has issued a successful call to listen().
* @param  addr       [OUT]    Either a null pointer, or a pointer to a sockaddr structure where the address of the connecting socket shall be returned.
* @param  addrlen    [IN/OUT] Either a null pointer, if address is a null pointer, or a pointer to a socklen_t object which on input specifies the length of the supplied sockaddr structure, and on output specifies the length of the stored address.
*
* @attention
* <ul>
* <li>This API does not support the PF_PACKET option.</li>
* </ul>
*
* @retval    #int     On success, accept() shall return the non-negative file descriptor of the accepted socket. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EWOULDBLOCK</b>: O_NONBLOCK is set for the socket file descriptor and no connections are present to be accepted.</li>
* <li><b>EWOULDBLOCK</b>: O_NONBLOCK is not set but SO_RCVTIMEO is set, and no connections are present within acception timeout.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNABORTED</b>: A connection has been aborted.</li>
* <li><b>EINVAL</b>: The socket is not accepting connections.</li>
* <li><b>ENFILE</b>: The maximum number of sockets in the system are already open.</li>
* <li><b>ENOBUFS</b>: No buffer space is available.</li>
* <li><b>ENOMEM</b>: There was insufficient memory available to complete the operation.</li>
* <li><b>EOPNOTSUPP</b>: The referenced socket is not of type SOCK_STREAM.</li>
* <li><b>EIO</b>: Internal errors.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  bind | connect | listen | socket
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
__socketcall int accept4(int, struct sockaddr*, socklen_t*, int);

/**
* @ingroup  socket
*
* @par Description:
* This API assigns the address specified by name to the socket referred to
* by the file descriptor 's'. namelen specifies the size, in bytes, of the address
* structure pointed to by name.
*
* @param  s        [IN]  Specifies the file descriptor of the socket to be bound.
* @param  name     [IN]  Points to a sockaddr structure containing the address to be bound to the socket. The length and format of the address depend on the address family of the socket.
* @param  namelen  [IN]  Specifies the length of the sockaddr structure pointed to by the address argument.
*
* @attention
* <ul>
* <li>Bind must not be called multiple times.</li>
* </ul>
*
* @retval     #0    On success.
* @retval     #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EADDRINUSE</b>: The specified address is already in use.</li>
* <li><b>EADDRINUSE</b>: For AF_INET socket, the port number was specified as zero in the socket address structure, but, upon attempting to bind to an ephemeral port, it was determined that all port numbers in the ephemeral port range are currently in use.</li>
* <li><b>EADDRNOTAVAIL</b>: The specified address is not available from the local machine.</li>
* <li><b>EAFNOSUPPORT</b>: The specified address is not a valid address for the address family of the specified socket.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EINVAL</b>: The socket is already bound to an address, and the protocol does not support binding to a new address.</li>
* <li><b>EINVAL</b>: The namelen argument is not a valid length for the address family.</li>
* <li><b>EINVAL</b>: For AF_PACKET socket, the ifindex is out of system netif index range.</li>
* <li><b>EISCONN</b>: The specified socket is already connected.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available to complete the call.</li>
* <li><b>ENODEV</b>: For AF_PACKET socket, the netif can not be determined by the ifindex.</li>
* <li><b>ENETDOWN</b>: For AF_PACKET socket, the netif determined by the ifindex was down.</li>
* <li><b>EOPNOTSUPP</b>: The socket type of the specified socket does not support binding to an address.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  connect | listen | socket
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int bind(int s, const struct sockaddr *name, int namelen);

/**
* @ingroup  socket
*
* @par Description:
* This API connects the socket referred to by the file descriptor 's' to the address specified by name.
*
* @param  s          [IN]  Specifies a socket file descriptor.
* @param  name       [IN]  Specifies a pointer to the sockaddr structure which identifies the connection.
* @param  namelen    [IN]  Specifies size of name.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EACCES</b>: The user tried to connect to a broadcast address without having the socket broadcast flag enabled.</li>
* <li><b>EADDRNOTAVAIL</b>: For AF_IENT socket, the socket had not previously been bound to an address and, upon attempting to bind it to an ephemeral port, it was determined that all port numbers in the ephemeral port range are currently in use.</li>
* <li><b>EAFNOSUPPORT</b>: The specified address is not a valid address for the address family of the specified socket.</li>
* <li><b>EALREADY</b>: The socket is nonblocking and a previous connection attempt has not yet been completed.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNREFUSED</b>: The target address was not listening for connections or refused the connection request.</li>
* <li><b>ECONNRESET</b>: Remote host reset the connection request.</li>
* <li><b>EINPROGRESS</b>: O_NONBLOCK is set for the file descriptor for the socket and the connection cannot be immediately established; the connection shall be established asynchronously.</li>
* <li><b>EINVAL</b>: The address_len argument is not a valid length for the address family.</li>
* <li><b>EISCONN</b>: The specified socket is connection-mode and is already connected.</li>
* <li><b>ENETUNREACH</b>: No route to the network is present.</li>
* <li><b>ENOBUFS</b>: No buffer space is available.</li>
* <li><b>EOPNOTSUPP</b>: The referenced socket is not of domain AF_INET.</li>
* <li><b>EOPNOTSUPP</b>: The socket is listening and cannot be connected.</li>
* <li><b>ETIMEDOUT</b>: The attempt to connect timed out before a connection was made.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  bind | listen | socket
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int connect(int s, const struct sockaddr *name, socklen_t namelen);

/**
* @ingroup  socket
*
* @par Description:
* This API returns the address of the peer connected to the socket 's', in the buffer pointed to by name.
* The namelen argument should be initialized  to  indicate the amount of space pointed to by name.
* On return it contains the actual size of the name returned (in bytes). The name is truncated if the
* buffer provided is too small.
*
* @param  s        [IN]      Specifies the file descriptor referring to the connected socket.
* @param  name     [OUT]     Pointer to sockaddr structure of remote peer
* @param  namelen  [IN/OUT]  Size of name structure.
*
* @attention
* <ul>
* <li>This API does not support the PF_PACKET option.</li>
* </ul>
*
* @retval     #0    On success.
* @retval     #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ENOTCONN</b>: The socket is not connected or otherwise has not had the peer pre-specified.</li>
* <li><b>EOPNOTSUPP</b>: The operation is not supported for the socket protocol.</li>
* <li><b>EINVAL</b>: The Name or Namelen are NULL, then EINVAL is returned.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  getsockname
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int getpeername(int s, struct sockaddr *name, socklen_t *namelen);

/**
* @ingroup  socket
*
* @par Description:
* This API returns the current address to which the socket 's'  is bound, in the buffer pointed to by name.
* The namelen argument should be initialized to indicate the amount of space(in bytes) pointed to by
* name.The returned address is truncated if the buffer provided is too small; in this case, namelen will
* return a value greater than was supplied to the call.
*
* @param  s       [IN]      Specifies the file descriptor referring to connected socket.
* @param  name    [OUT]     Pointer to sockaddr structure of local peer.
* @param  namelen [IN/OUT]  Size of name structure.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EOPNOTSUPP</b>: The operation is not supported for this socket's protocol.For PF_RAW sockets, this error is returned.</li>
* <li><b>EINVAL</b>: The Name or Namelen are NULL, then EINVAL is returned.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  getpeername
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int getsockname(int s, struct sockaddr *name, socklen_t *namelen);

/**
* @ingroup  socket
*
* @par Description:
* This API retrieves the value for the option specified by the optname argument for the socket
* specified by 's'. If the size of the optval is greater than optlen, the value stored in the object
* pointed to by the optval argument shall be silently truncated.
*
* @param  s        [IN]      Specifies a socket file descriptor.
* @param  level    [IN]      Specifies the protocol level at which the option resides.
* @param  optname  [IN]      Specifies a single option to be retrieved.
* @param  optval   [OUT]     Indicates an address to store option value.
* @param  optlen   [IN/OUT]  Specifies the size of the option value.
*
* @attention
* <ul>
* <li>Supported protocol levels are: SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP,IPPROTO_UDPLITE.</li>
* <li>Under SOL_SOCKET the options supported are:
* SO_ACCEPTCONN
* SO_BROADCAST
* SO_ERROR
* SO_KEEPALIVE
* SO_SNDTIMEO
* SO_RCVTIMEO
* SO_RCVBUF
* SO_SNDBUF
* SO_REUSEADDR
* SO_TYPE
* SO_NO_CHECK
* SO_DONTROUTE
* SO_BINDTODEVICE
* For SO_SNDTIMEO, SO_RCVTIMEO, SO_RCVBUF, the macros LWIP_SO_SNDTIMEO, LWIP_SO_RCVTIMEO and LWIP_SO_RCVBUF should have been defined at compile time.
* For SO_REUSEADDR, the macro SO_REUSE should have been defined at compile time.
* For SO_BINDTODEVICE, the macro LWIP_SO_BINDTODEVICE should have been defined at compile time.
* For SO_SNDBUF, the macro LWIP_SO_SNDBUF should have been defined at compile time.
* </li>
* <li>Under IPPROTO_IP the options supported are:
* IP_MULTICAST_TTL
* IP_MULTICAST_LOOP
* IP_MULTICAST_IF
* IP_HDRINCL
* IP_TTL
* IP_TOS
* Only UDP socket supports IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_MULTICAST_IF.
* </li>
* <li>Under IPPROTO_TCP the options supported are:
* TCP_NODELAY
* TCP_KEEPIDLE
* TCP_KEEPINTVL
* TCP_KEEPCNT
* TCP_INFO
* TCP_QUEUE_SEQ.
* For TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT, the macro LWIP_TCP_KEEPALIVE should have been defined at compile time.\n
* For TCP_INFO, Only tcpi_state, tcpi_retransmits, tcpi_probes, tcpi_backoff, tcpi_options, tcpi_rto, tcpi_snd_mss, tcpi_rcv_mss, tcpi_unacked,
* tcpi_rtt, tcpi_rttvar, tcpi_snd_ssthresh, tcpi_snd_cwnd, tcpi_reordering in
* struct tcp_info are supported, other fields are keep 0.
* </li>
* <li>Under IPPROTO_UDPLITE the options supported are:
* UDPLITE_SEND_CSCOV
* UDPLITE_RECV_CSCOV
* </li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EINVAL</b>: The specified option is invalid at the specified socket level.</li>
* <li><b>EINVAL</b>: If opt or optlen are NULL,option or option length is incorrect.</li>
* <li><b>ENOPROTOOPT</b>: The option is not supported by the protocol.</li>
* <li><b>ENOMEM</b>: There was insufficient memory available to complete the operation.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  setsockopt
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);

/**
* @ingroup  socket
*
* @par Description:
* This API marks the socket referred to by 's' as a passive socket, that is, as a socket that will be used
* to accept incoming connection requests using accept().
*
* @param  s          [IN]  Specifies a file descriptor that refers to a socket of type SOCK_STREAM.
* @param  backlog    [IN]  Defines the maximum length to which the queue of pending connections for 's' may grow. If a connection request arrives when the queue is full, the client may receive an error with
*      an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.
*
* @attention
* <ul>
* <li>Max value of backlog is 0xFF, and min value of backlog is 0.</li>
* <li>If backlog value is 0 or less than zero, backlog value of 1 is used.</li>
* <li>This API does not support the PF_PACKET socket.</li>
* <li>lwIP do not support auto binding in listen operation, so bind must be called before listen.</li>
* <li>Listen can only be called once, and the backlog value can not be changed by later calling.</li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EDESTADDRREQ</b>: The socket is not bound to a local address, and the protocol does not support listening on an unbound socket.</li>
* <li><b>EINVAL</b>: The socket is in state which is not acceptable for listen.</li>
* <li><b>ENOBUFS</b>: Insufficient resources are available in the system to complete the call.</li>
* <li><b>EOPNOTSUPP</b>: The socket protocol does not support listen().</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  bind | connect | socket
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int listen(int s, int backlog);
__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*);
__socketcall int sendmmsg(int, const struct mmsghdr*, unsigned int, int);

/**
* @ingroup  socket
*
* @par Description:
*  This API initiates transmission of a message from the specified socket to its peer.
*  It sends a message only when the socket is connected.  The sendmsg() call also allows
* sending ancillary data (also known as control information).
*
* @param    s       [IN]   Specifies the socket file descriptor.
* @param    message [IN]   Specifies a buffer containing message to send.
* @param    flags   [IN]   Indicates the flags of message transmission.
*
* @attention
* <ul>
* <li>This API is only supported since lwip 2.0.</li>
* <li>UDP and RAW connection can send only data of maximum length 65332. Sending more than data
* will return -1 and errno set to EMSGSIZE</li>
* <li>Only flag MSG_MORE and MSG_DONTWAIT is supported. Other flags, such as
* MSG_OOB/MSG_NOSIGNAL/MSG_EOR are not supported.</li>
* </ul>
*
* @retval    #int      On success, sendmsg() shall return the number of bytes sent. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EADDINUSE</b>: For PF_INET/SOCK_DGRAM socket without local port bond, when attempting to
* bind to an ephemeral port, it was determined that all port numbers in the ephemeral port range are currently in use.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNRESET</b>: A connection was forcibly closed by a peer.</li>
* <li><b>EDESTADDRREQ</b>: The socket is not connection-mode and does not have its peer address set.</li>
* <li><b>EINPROGRESS</b>: For PF_INET/SOCK_STREAM, there was one send operation in progress,
* and concurrent sending was not supported.</li>
* <li><b>EINVAL</b>: Invalid argument passed, e.g. dataptr is NULL, size is zero.</li>
* <li><b>EMSGSIZE</b>: The socket type requires that message be sent atomically, and the size of the message
* to be sent made this impossible. For PF_PACKET/SOCK_RAW socket, it means the packet is larger than the MTU of out network interface. For PF_INET/(SOCK_RAW,SOCK_DGRAM) socket, it means the packet is larger than 65000 bytes.</li>
* <li><b>ENETDOWN</b>: For PF_PACKET/SOCK_RAW socket, the binding network interface was down.</li>
* <li><b>ENOBUFS</b>: The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible. For PF_PACKET/SOCK_RAW socket, it means the packet is larger than the MTU of out network interface. For PF_INET/(SOCK_RAW,SOCK_DGRAM) socket, it means the packet is larger than 65000 bytes.</li>
* <li><b>ENETDOWN</b>: For PF_PACKET/SOCK_RAW socket, the binding network interface was down.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>ENODEVADDR</b>: For PF_PACKET/SOCK_RAW socket, the binding network interface does not exist.</li>
* <li><b>ENOMEM</b>: Insufficient memory was available to fulfill the request.</li>
* <li><b>ENOTCONN</b>: The socket is not connected.</li>
* <li><b>EOPNOTSUPP</b>: Some bit in the flags argument is unsupported for the socket type.</li>
* <li><b>EPIPE</b>: The socket is shut down for writing, or the socket is connection-mode
* and is no longer connected. In the latter case, and if the socket is of type SOCK_STREAM.</li>
* <li><b>EWOULDBLOCK</b>: The socket's file descriptor is marked O_NONBLOCK or MSG_DONWAIT flag is set and the requested operation would block.</li>
* <li><b>EWOULDBLOCK</b>: The socket was not marked with O_NONBLOCK, but set with option SO_SNDTIMEO, and elapsed time is more than timeout value.</li>
* <li><b>EIO</b>: Internal errors.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  sendto
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int sendmsg(int s, const struct msghdr *message, int flags);

/**
* @ingroup  socket
*
* @par Description:
* This API sets the option specified by the optname, at the protocol level specified by the level,
* to the value pointed to by the optval for the socket associated with the file descriptor specified by 's'.
*
* @param  s        [IN]      Specifies a socket file descriptor.
* @param  level    [IN]      Specifies the protocol level at which the option resides.
* @param  optname  [IN]      Specifies a single option to set.
* @param  optval   [IN]      Indicates the address to store the option value.
* @param  optlen   [IN]      Specifies the size of option value.
*
* @attention
* <ul>
* <li>Supported protocol levels are: SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP,IPPROTO_UDPLITE.</li>
* <li>Under SOL_SOCKET the options supported are:
* SO_BROADCAST
* SO_KEEPALIVE
* SO_SNDTIMEO
* SO_RCVTIMEO
* SO_RCVBUF
* SO_SNDBUF
* SO_REUSEADDR
* SO_REUSEPORT
* SO_NO_CHECK.
* SO_ATTACH_FILTER
* SO_DETACH_FILTER
* SO_DONTROUTE
* SO_BINDTODEVICE
* For SO_SNDTIMEO, SO_RCVTIMEO, SO_RCVBUF, the macros LWIP_SO_SNDTIMEO, LWIP_SO_RCVTIMEO and LWIP_SO_RCVBUF should have been defined at compile time.
* For SO_REUSEADDR, the macro SO_REUSE should have been defined at compile time.
* For SO_BINDTODEVICE, the macro LWIP_SO_BINDTODEVICE should have been defined at compile time.
* For SO_ATTACH_FILTER, SO_DETACH_FILTER, the macro LWIP_SOCKET_FILTER should have been defined at compile time.
* Only PF_PACKET RAW socket supports SO_ATTACH_FILTER and SO_DETACH_FILTER now.
* For SO_SNDBUF, the macro LWIP_SO_SNDBUF should have been defined at compile time.
* Only TCP socket in listen or closed stated supports SO_SNDBUF.
* </li>
* <li>Under IPPROTO_IP the options supported are:
* IP_ADD_MEMBERSHIP
* IP_DROP_MEMBERSHIP
* IP_MULTICAST_TTL
* IP_MULTICAST_LOOP
* IP_MULTICAST_IF
* IP_HDRINCL
* IP_TTL
* IP_TOS
* Only UDP socket supports IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_MULTICAST_IF.
* </li>
* <li>Under IPPROTO_TCP the options supported are:
* TCP_NODELAY
* TCP_KEEPIDLE
* TCP_KEEPINTVL
* TCP_KEEPCNT.
* For TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT, the macro LWIP_TCP_KEEPALIVE should have been defined at compile time.
* </li>
* <li>Under IPPROTO_UDPLITE the options supported are:
* UDPLITE_SEND_CSCOV
* UDPLITE_RECV_CSCOV
* </li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EDOM</b>: The send and receive timeout values are too big to fit into the timeout fields in the socket structure.</li>
* <li><b>ENOENT</b>: the option is SO_DETACH_FILTER while no previous socket filter was attached.</li>
* <li><b>ENOMEM</b>: There was insufficient memory available for the operation to complete.</li>
* <li><b>ENOPROTOOPT</b>: The option is not supported by the protocol.</li>
* <li><b>EINVAL</b>: If optval is NULL pointer, lwIP shall fail.</li>
* <li><b>EINVAL</b>: If for PF_PACKET socket type, level is neither SOL_PACKET nor SOL_SOCKET, lwIP shall fail.</li>
* <li><b>EINVAL</b>: If optlen does not match optval for corresponding optname, lwIP shall fail.</li>
* <li><b>EINVAL</b>: If the send and receive timeout values are smaller than 10000 microseconds, lwIP shall fail.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  getsockopt
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);

/**
* @ingroup  socket
*
* @par Description:
* This API is used to shut down socket send and receive operations.
*
* @param  s    [IN]  Specifies a file descriptor referring to the socket.
* @param  how  [IN]  Specifies the type of shutdown. The values are as follows: \n SHUT_RD Disables further receive operations. SHUT_WR: Disables further send operations. SHUT_RDWR: Disables further send and receive operations.
*
* @attention
* <ul>
* <li>Only "SHUT_RDWR" is supported for the "how" parameter in this API. lwIP does not support closing one end of the full-duplex connection.</li>
* <li>This API does not support the PF_PACKET option.</li>
* <li>The listen socket does not support half shutdown.</li>
* </ul>
*
* @retval    #0    On success.
* @retval    #-1   On failure.
*
* @par Errors
* <ul>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>EINVAL</b>: The how argument is invalid.</li>
* <li><b>ENOTCONN</b>: lwIP does not support half close, ENOTCONN is returned.</li>
* <li><b>EINPROGRESS</b>: If WRITE/CONNECTING/CLOSE is in progress, lwip may fail.</li>
* <li><b>EINVAL</b>: If socket is not connected, lwIP shall fail with EINVAL.</li>
* <li><b>ENOMEM</b>: There was insufficient memory available to complete the operation.</li>
* <li><b>EOPNOTSUPP</b>: Socket is not TCP, lwIP shall fail.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  None
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int shutdown(int s, int how);

/**
* @ingroup  socket
*
* @par Description:
* This API is used to create an endpoint for communication and returns a file descriptor.
*
* @param    domain    [IN]  Specifies a protocol family.
* @param    type      [IN]  Specifies the socket type.  [SOCK_RAW|SOCK_DGRAM|SOCK_STREAM]
* @param    protocol  [IN]  Specifies the protocol to be used with the socket.
*
* @attention
* <ul>
* <li>Only domain AF_INET and AF_PACKET are supported. For AF_INET, type SOCK_RAW|SOCK_DGRAM|SOCK_STREAM is supported.
* For AF_PACKET, only type SOCK_RAW is supported.</li>
* <li>The type argument can only be used to specify the socket type, no flags is supported, such as SOCK_NONBLOCK and SOCK_CLOEXEC.</li>
* </ul>
*
* @retval    #int    On success, socket() shall return a non-negative integer, the socket file descriptor. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EAFNOSUPPORT</b>: The implementation does not support the specified address family.</li>
* <li><b>EINVAL</b>: Invalid type or invalid flags in type.</li>
* <li><b>ENFILE</b>: The maximum number of sockets in the system are already open.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>EPROTONOSUPPORT</b>: The specified protocol is not supported within this domain & type.</li>
* <li><b>ESOCKTNOSUPPORT</b>: The socket type is not supported within this domain.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  None
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall int socket(int domain, int type, int protocol);
__socketcall int socketpair(int, int, int, int*);

/**
* @ingroup  socket
*
* @par Description:
* This API initiate transmission of a message from the specified socket to its peer.
* This API will send a message only when the socket is connected.
*
* @param    s       [IN]   Specifies the socket file descriptor.
* @param    dataptr [IN]   Specifies a buffer containing message to send.
* @param    size    [IN]   Specifies the length of the message to send.
* @param    flags   [IN]   Indicates the flags of message transmission.
*
* @attention
* <ul>
* <li>UDP & RAW connection can send only a maximum data of length 65000. Sending more data would
* return -1 and errno set to EMSGSIZE.</li>
* <li>Only flag MSG_MORE, MSG_DONTWAIT and MSG_NOSIGNAL are supported, other flags, such as MSG_OOB/MSG_EOR is not supported.</li>
* </ul>
*
* @retval    #ssize_t      On success, send() shall return the number of bytes sent. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EWOULDBLOCK</b>: The socket's file descriptor is marked O_NONBLOCK or MSG_DONWAIT flag is set and the requested operation would block.</li>
* <li><b>EWOULDBLOCK</b>: The socket was not marked with O_NONBLOCK, but set with option SO_SNDTIMEO, and elapsed time is more than timeout value.</li>
* <li><b>EADDINUSE</b>: For PF_INET/SOCK_DGRAM socket without local port bond, when attempting to bind to an ephemeral port, it was determined that all port numbers in the ephemeral port range are currently in use.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNRESET</b>: A connection was forcibly closed by a peer.</li>
* <li><b>EDESTADDRREQ</b>: The socket is not connection-mode and does not have its peer address set.</li>
* <li><b>EINPROGRESS</b>: For PF_INET/SOCK_STREAM, there was one send operation in progress, and concurrent sending was not supported.</li>
* <li><b>EINVAL</b>: Invalid argument passed, e.g. dataptr is NULL, size is zero.</li>
* <li><b>EMSGSIZE</b>: The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible. For PF_PACKET/SOCK_RAW socket, it means the packet is larger than the MTU of out network interface. For PF_INET/(SOCK_RAW,SOCK_DGRAM) socket, it means the packet is larger than 65000 bytes.</li>
* <li><b>ENETDOWN</b>: For PF_PACKET/SOCK_RAW socket, the binding network interface was down.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>ENOMEM</b>: Insufficient memory was available to fulfill the request.</li>
* <li><b>ENODEVADDR</b>: For PF_PACKET/SOCK_RAW socket, the binding network interface does not exist.</li>
* <li><b>ENOTCONN</b>: The socket is not connected.</li>
* <li><b>EOPNOTSUPP</b>: Some bit in the flags argument is unsupported for the socket type.</li>
* <li><b>EIO</b>: Internal errors.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  sendto
*
* @since Huawei LiteOS V100R001C00
*/
extern ssize_t send(int s, const void *dataptr, size_t size, int flags);

/**
* @ingroup  socket
*
* @par Description:
* This API can be used to receive messages from a connection-oriented sockets only
* because it doesnot permits the application to retrieve the source address of received data.
*
* @param  s          [IN]  Specifies the socket file descriptor.
* @param  mem        [IN]  Points to a buffer where the message should be stored.
* @param  len        [IN]  Specifies the length in bytes of the buffer pointed to by the 'mem' argument.
* @param  flags      [IN]  Specifies the type of message reception. Values of this argument are formed by logically OR'ing zero or more of the following values: MSG_PEEK
*                          Peeks at an incoming message. The data is treated as unread and the next recv() or similar function shall still return this data.
*
* @attention
* <ul>
* <li>LwIP updates this receive buffer list, once it gets the next expected segment.
* If there is any out of order segment which is next to the received segment, means
* it merges and puts that as one segemnt into receive buffer list.</li>
* <li>If the apps don't read the packet from the socket and the recv buffered
* packets up to MAX_MBOX_SIZE, the incoming packet may be discard by lwIP and cause
* retransmission for tcp connection.</li>
* <li>Only flag MSG_PEEK and MSG_DONTWAIT are supported, other flags, such as MSG_TRUNC/MSG_WAITALL/MSG_OOB is not supported.</li>
* <li>When RST is received after FIN, this API will return 0 to indicate FIN, then
* return -1 and set errno to ECONNRESET for RST if called again.</li>
* <li>This API is not thread-safe.</li>
* </ul>
*
* @retval    #ssize_t    On success, recv() shall return the length of the message in bytes. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EWOULDBLOCK</b>: The socket's file descriptor is marked O_NONBLOCK or MSG_DONTWAIT flag is set and no data is waiting to be received.</li>
* <li><b>EWOULDBLOCK</b>: The socket was not marked with O_NONBLOCK, but set with option SO_RCVTIMEO, and elapsed time is more than timeout value.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNRESET</b>: A connection was forcibly closed by a peer.</li>
* <li><b>EINVAL</b>: Invalid input parameters. If mem, len is null or flags is less than zero, lwip return failure.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>ENOMEM</b>: Insufficient memory was available to fulfill the request.</li>
* <li><b>ENOTCONN</b>: A receive is attempted on a connection-mode socket that is not connected.</li>
* <li><b>EOPNOTSUPP</b>: Some bit in the flags argument is unsupported for the socket type.</li>
* <li><b>EIO</b>: Internal errors.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  recvfrom
*
* @since Huawei LiteOS V100R001C00
*/
extern ssize_t recv(int s, void *mem, size_t len, int flags);

/**
* @ingroup  socket
*
* @par Description:
* This API can be used to send messages to a connection-oriented or connectionless socket.
* If the socket is connectionless-mode, the message shall be sent to the address specified by 'to'.
* If the socket is connection-mode, destination address in 'to' shall be ignored.
*
* @param    s        [IN]  Specifies a socket file descriptor.
* @param    dataptr  [IN]  Specifies a buffer containing the message to send.
* @param    size     [IN]  Specifies the length of the message to send.
* @param    flags    [IN]  Indicates the flags of message transmission.
* @param    to       [IN]  Specifies a pointer to the sockaddr structure that contains the destination address.
* @param    tolen    [IN]  Specifies the size of the 'to' structure.
*
* @attention
* <ul>
* <li>UDP & RAW connection can send only a maximum data of length 65000. Sending more data would
* return -1 and errno set to EMSGSIZE.</li>
* <li>Only flag MSG_MORE, MSG_DONTWAIT and MSG_NOSIGNAL are supported, other flags, such as MSG_OOB/MSG_EOR is not supported.</li>
* </ul>
*
* @retval    #ssize_t       On success, sendto() shall return the number of bytes sent. On failure, -1 shall be returned.
*
* @par Errors
* <ul>
* <li><b>EWOULDBLOCK</b>: The socket's file descriptor is marked O_NONBLOCK or MSG_DONTWAIT flag is set and the requested operation would block.</li>
* <li><b>EWOULDBLOCK</b>: The socket was not marked with O_NONBLOCK, but set with option SO_SNDTIMEO, and elapsed time is more than timeout value.</li>
* <li><b>EACCES</b>: For PF_INET/(SOCK_RAW,SOCK_DGRAM) socket, the destination address is broadcast but SO_BROADCAST option was not enabled.</li>
* <li><b>EADDINUSE</b>: For PF_INET/SOCK_DGRAM socket without local port bond, when attempting to bind to an ephemeral port, it was determined that all port numbers in the ephemeral port range are currently in use.</li>
* <li><b>EAFNOSUPPORT</b>: Addresses in the specified address family cannot be used with this socket.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNRESET</b>: A connection was forcibly closed by a peer.</li>
* <li><b>EDESTADDRREQ</b>: The socket is not connection-mode and does not have its peer address set, and no destination address was specified.</li>
* <li><b>EINPROGRESS</b>: For PF_INET/SOCK_STREAM, there was one send operation in progress, and concurrent sending was not supported.</li>
* <li><b>EINVAL</b>: Invalid argument passed, e.g. dataptr is NULL, size is zero.</li>
* <li><b>EMSGSIZE</b>: The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible. For PF_PACKET/SOCK_RAW socket, it means the packet is larger than the MTU of out network interface. For PF_INET/(SOCK_RAW,SOCK_DGRAM) socket, it means the packet is larger than 65000 bytes.</li>
* <li><b>ENETDOWN</b>: For PF_PACKET/SOCK_RAW socket, the out network interface was down.</li>
* <li><b>ENETUNREACH</b>: No route to the destination is present.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>ENXIO</b>: For PF_PACKET/SOCK_RAW socket, the given network interface does not exist.</li>
* <li><b>ENOMEM</b>: Insufficient memory was available to fulfill the request.</li>
* <li><b>ENOTCONN</b>: The socket is not connected.</li>
* <li><b>EOPNOTSUPP</b>: Some bit in the flags argument is unsupported for the socket type.</li>
* <li><b>EIO</b>: Internal error.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  send
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall ssize_t sendto(int s, const void *dataptr, size_t size, int flags,
    const struct sockaddr *to, socklen_t tolen);

/**
* @ingroup  socket
*
* @par Description:
* This API can be used to receive messages from a connection-oriented and connectionless sockets
* because it permits the application to retrieve the source address of received data.
*
* @param    s         [IN]   Specifies the socket file descriptor.
* @param    mem       [IN]   Points to the buffer where the message should be stored.
* @param    len       [IN]   Specifies the length in bytes of the buffer pointed to by the buffer argument.
* @param    flags     [IN]   Specifies the type of message reception. Values of this argument are formed by logically OR'ing zero or more of the following values: MSG_PEEK Peeks at an incoming message. The data is treated as unread and the next recvfrom() or similar function shall still return this data.
* @param    from      [OUT]  A null pointer, or points to a sockaddr structure in which the sending address is to be stored. The length and format of the address depend on the address family of the socket.
* @param    fromlen   [OUT]  Either a null pointer, if address is a null pointer, or a pointer to a socklen_t object which on input specifies the length of the supplied sockaddr structure, and on output specifies the length of the stored address.
*
* @attention
* <ul>
* <li>If the apps don't read the packet from the socket and the recv buffered
* packets up to MAX_MBOX_SIZE, the incoming packet may be discard by lwIP.</li>
* <li>For TCP connection, when RST is received after FIN, this API will return
* 0 to indicate FIN, then return -1 and set errno to ECONNRESET for RST if
* called again.</li>
* <li>Only flag MSG_PEEK and MSG_DONTWAIT are supported, other flags, such as MSG_TRUNC/MSG_WAITALL/MSG_OOB is not supported.</li>
* <li>This API is not thread-safe.</li>
* </ul>
*
* @retval     #ssize_t      On success, recvfrom() shall return the length of the message in bytes. On failure, the function shall return -1.
*
* @par Errors
* <ul>
* <li><b>EWOULDBLOCK</b>: The socket's file descriptor is marked O_NONBLOCK or MSG_DONTWAIT flag is set and no data is waiting to be received.</li>
* <li><b>EWOULDBLOCK</b>: The socket was not marked with O_NONBLOCK, but set with option SO_RCVTIMEO, and elapsed time is more than timeout value.</li>
* <li><b>EBADF</b>: The socket argument is not a valid file descriptor.</li>
* <li><b>ECONNRESET</b>: A connection was forcibly closed by a peer.</li>
* <li><b>EINVAL</b>: Invalid input parameters. If mem, len is null or flags is less than zero, lwip return failure.</li>
* <li><b>ENOBUFS</b>: Insufficient resources were available in the system to perform the operation.</li>
* <li><b>ENOMEM</b>: Insufficient memory was available to fulfill the request.</li>
* <li><b>ENOTCONN</b>: A receive is attempted on a connection-mode socket that is not connected.</li>
* <li><b>EOPNOTSUPP</b>: Some bit in the flags argument is unsupported for the socket type.</li>
* <li><b>EIO</b>: Internal errors.</li>
* </ul>
*
* @par Dependency:
* <ul><li>socket.h</li></ul>
*
* @see  recv
*
* @since Huawei LiteOS V100R001C00
*/
__socketcall ssize_t recvfrom(int s, void *mem, size_t len, int flags,
      struct sockaddr *from, socklen_t *fromlen);

__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
extern ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*, socklen_t*);
extern ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);

#if defined(__BIONIC_FORTIFY)

__BIONIC_FORTIFY_INLINE
ssize_t recvfrom(int fd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len) {
  size_t bos = __bos0(buf);

#if !defined(__clang__)
  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
  }

  if (__builtin_constant_p(len) && (len <= bos)) {
    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
  }

  if (__builtin_constant_p(len) && (len > bos)) {
    __recvfrom_error();
  }
#endif

  return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
}

__BIONIC_FORTIFY_INLINE
ssize_t recv(int socket, void* buf, size_t len, int flags) {
  return recvfrom(socket, buf, len, flags, NULL, 0);
}

#endif /* __BIONIC_FORTIFY */

#undef __socketcall


#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

#endif /* _SYS_SOCKET_H */
